// === ArchivalDao.java ===
package com.cardgame.dao;

import com.cardgame.model.deck.Deck;
import com.cardgame.model.archival.Archival;
import lombok.Getter;
import org.springframework.stereotype.Repository;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.*;
import java.util.*;

@Repository
public class ArchivalDao implements IArchivalDao {
    private static final String ARCHIVAL_DATA_PATH = "data/archival.json";
    private final ObjectMapper objectMapper = new ObjectMapper();
    // 获取当前存档对象
    @Getter
    private Archival archival;
    private boolean initialized = false;

    // 构造函数，初始化并加载存档
    public ArchivalDao() {
        init();
    }

    // 初始化时加载存档数据，只加载一次
    public void init() {
        if (initialized)
            return;
        loadArchival();
        initialized = true;
    }

    // 加载存档数据，若无文件则创建默认存档
    private void loadArchival() {
        try {
            File file = new File(ARCHIVAL_DATA_PATH);
            if (!file.exists()) {
                createDefaultArchival();
            } else {
                archival = objectMapper.readValue(file, Archival.class);
                syncDeckIdCounter(); // 同步Deck类的ID计数器，避免ID冲突
            }
        } catch (Exception e) {
            e.printStackTrace();
            // createDefaultArchival();
        }
    }

    // 同步Deck类的ID计数器，避免新增卡组时ID重复
    private void syncDeckIdCounter() {
        try {
            int maxDeckId = archival.getDecks().stream()
                    .mapToInt(Deck::getId)
                    .max().orElse(0);
            java.lang.reflect.Field field = Deck.class.getDeclaredField("nextId");
            field.setAccessible(true);
            field.set(null, maxDeckId + 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 创建默认的初始存档数据，包括金币、卡牌与默认卡组
    private void createDefaultArchival() {
        archival = new Archival();
        archival.setMoney(1000);

        // 添加初始卡牌
        Map<Integer, Integer> initialCards = new HashMap<>();
        initialCards.put(1, 3); // 三个1级战士卡
        initialCards.put(31, 5); // 5个1级加最大蓝量
        initialCards.put(41, 5); // 5个1级治疗
        initialCards.put(51, 5); // 5个1级加蓝
        initialCards.put(61, 5); // 1个全局装备卡
        initialCards.put(71, 5); // 1个1级战士剑
        archival.setCards(initialCards);

        // 添加初始角色
        List<Integer> initialRoles = new ArrayList<>();
        initialRoles.add(1);
        archival.setRoles(initialRoles);

        // 构造初始卡组
        List<Deck> initialDecks = new ArrayList<>();

        // 构造敌方卡组
        Map<Integer, Integer> enemyCards1 = new HashMap<>();
        enemyCards1.put(1, 3); // 三个1级战士卡
        enemyCards1.put(31, 5); // 5个1级加最大蓝量
        enemyCards1.put(41, 5); // 5个1级治疗
        enemyCards1.put(51, 5); // 5个1级加蓝
        enemyCards1.put(61, 1); // 1个全局装备卡
        enemyCards1.put(71, 3); // 3个1级战士剑
        Deck enemyDeck1 = new Deck("战士卡组", 1, enemyCards1);
        enemyDeck1.setPlayerControlled(false); // 标记为敌方
        // 构造敌方卡组2
        Map<Integer, Integer> enemyCards2 = new HashMap<>();
        enemyCards2.put(5, 5); // 三个1级战士卡
        enemyCards2.put(31, 1); // 1个1级加最大蓝量
        enemyCards2.put(32, 1); // 1个2级加最大蓝量
        enemyCards2.put(33, 1); // 1个3级加最大蓝量
        enemyCards2.put(34, 1); // 1个4级加最大蓝量
        enemyCards2.put(35, 1); // 1个5级加最大蓝量
        enemyCards2.put(45, 5); // 5个1级治疗
        enemyCards2.put(55, 5); // 5个1级加蓝
        enemyCards2.put(65, 1); // 1个全局装备卡
        enemyCards2.put(75, 3); // 3个1级战士剑
        Deck enemyDeck2 = new Deck("战士卡组", 5, enemyCards2);
        enemyDeck2.setPlayerControlled(false); // 标记为敌方
        // 构造敌方卡组3
        Map<Integer, Integer> enemyCards3 = new HashMap<>();
        enemyCards3.put(10, 10); // 三个1级战士卡
        enemyCards3.put(31, 5); // 1个1级加最大蓝量
        enemyCards3.put(32, 5); // 1个2级加最大蓝量
        enemyCards3.put(33, 5); // 1个3级加最大蓝量
        enemyCards3.put(34, 5); // 1个4级加最大蓝量
        enemyCards3.put(35, 5); // 1个5级加最大蓝量
        enemyCards3.put(50, 5); // 5个1级治疗
        enemyCards3.put(55, 10); // 5个1级加蓝
        enemyCards3.put(70, 1); // 1个全局装备卡
        enemyCards3.put(80, 3); // 3个1级战士剑
        Deck enemyDeck3 = new Deck("战士卡组", 10, enemyCards3);
        enemyDeck3.setPlayerControlled(false); // 标记为敌方

        // 构造玩家卡组
        Map<Integer, Integer> warriorCards = new HashMap<>();
        warriorCards.put(1, 3); // 三个1级战士卡
        warriorCards.put(31, 5); // 5个1级加最大蓝量
        warriorCards.put(41, 5); // 5个1级治疗
        warriorCards.put(51, 5); // 5个1级加蓝
        warriorCards.put(61, 1); // 1个全局装备卡
        warriorCards.put(71, 1); // 1个1级战士剑
        Deck warriorDeck = new Deck("战士卡组", 1, warriorCards);

        initialDecks.add(enemyDeck1);
        initialDecks.add(enemyDeck2);
        initialDecks.add(enemyDeck3);
        initialDecks.add(warriorDeck);
        archival.setDecks(initialDecks);

        saveArchival();
    }

    // 将当前存档数据写入文件
    public void saveArchival() {
        try {
            System.out.println("[存档] 正在保存到文件...");
            File file = new File(ARCHIVAL_DATA_PATH);
            file.getParentFile().mkdirs();
            objectMapper.writeValue(file, archival);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 根据卡组ID查找对应Deck
    public Deck getDeckById(Integer deckId) {
        return archival.getDecks().stream()
                .filter(deck -> deck.getId().equals(deckId))
                .findFirst()
                .orElse(null);
    }

    // 更新金币数并保存
    public void updateMoney(Integer money) {
        archival.setMoney(money);
        saveArchival();
    }

    // 增加卡牌（数量+1）并保存
    public void addCard(Integer cardId) {
        archival.addCard(cardId);
        saveArchival();
    }

    // 删除某张卡牌记录（注意：这是直接删除所有该卡牌）
    public void removeCard(Integer cardId) {
        archival.getCards().remove(cardId);
        saveArchival();
    }

    // 添加卡组并保存
    public void addDeck(Deck deck) {
        archival.getDecks().add(deck);
        saveArchival();
    }

    // 更新已有卡组内容
    public void updateDeck(Deck deck) {
        for (int i = 0; i < archival.getDecks().size(); i++) {
            if (archival.getDecks().get(i).getId().equals(deck.getId())) {
                archival.getDecks().set(i, deck);
                saveArchival();
                break;
            }
        }
    }

    // 删除指定ID的卡组
    public void removeDeck(Integer deckId) {
        archival.getDecks().removeIf(deck -> deck.getId().equals(deckId));
        saveArchival();
    }
}
